package com.vvlive.caibao.smartcity.fragment;

import android.app.Activity;
import android.content.Intent;
import android.graphics.drawable.BitmapDrawable;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.view.ViewGroup;
import android.widget.PopupWindow;
import android.widget.TextView;

import com.vvlive.caibao.smartcity.base.BaseFragment;
import com.vvlive.caibao.smartcity.base.CalendarViews;
import com.vvlive.caibao.smartcity.base.MeetingsListInterface;
import com.vvlive.caibao.smartcity.bean.Dept;
import com.vvlive.caibao.smartcity.bean.EventCard;
import com.vvlive.caibao.smartcity.bean.MeetingByMonth;
import com.vvlive.caibao.smartcity.bean.MeetingRoom;
import com.vvlive.caibao.smartcity.bean.NewMeetingInfo;
import com.vvlive.caibao.smartcity.ui.MeetingDetailsActivity;
import com.vvlive.caibao.smartcity.ui.OrderOneMeetingActivity;
import com.vvlive.caibao.smartcity.utils.MeetingsController;
import com.vvlive.caibao.smartcity.utils.ScreenUtil;
import com.vvlive.caibao.smartcity.view.EventCardView;
import com.vvlive.caibao.smartcity.view.HoursView;
import com.vvlive.caibao.smartcity.view.HoursView.OnHourClickListener;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import smartcity.vvlive.caibao.com.smartc.R;

/**
 * Created by zhj on 2015/10/15.
 * 会议的日历日视图
 */
public class DayViewFragment extends BaseFragment implements CalendarViews {

    /**
     * 半小时高度
     */
    private static final int HALF_AN_HOUR_HEIGHT = 48;
    private static final int SCROLL_DELAY_WHAT = 101;
    private static final int SCROLL_DELAY_MILLIS = 200;

    private HoursView mHours;
    private Calendar mCalendar;
    private int mMonth;
    private MeetingsListInterface mListInterface;
    private Dept mDept;
    private MeetingRoom mRoom;
    private ScreenUtil mScreen;

    private OnRefreshListener mRefresh;

    private int mToday = -1;

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        if (activity instanceof MeetingsListInterface) {
            mListInterface = (MeetingsListInterface) activity;
        }
    }

    public DayViewFragment() {
        mCalendar = Calendar.getInstance();
        mMonth = mCalendar.get(Calendar.MONTH);
        mToday = getDayOfYear();
    }

    /**
     *
     */
    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            int what = msg.what;
            if (what == SCROLL_DELAY_WHAT) {
                // 让时间滑动到当前的时间点
                mHours.smoothScrollTo(0, getOffsetTopByHour(mCalendar.get(Calendar.HOUR_OF_DAY) * 2));
            }

        }
    };

    @Override
    public int getContentRes() {
        return R.layout.fragment_day_view;
    }

    private PreparedListener mPreparedListener;
    private HoursCallBack mHoursCallBack;

    @Override
    public void initFragment() {

        mHours = findView(R.id.meeting_hours);
        mHandler.sendEmptyMessageDelayed(SCROLL_DELAY_WHAT, SCROLL_DELAY_MILLIS);

        mPreparedListener = new PreparedListener();
        mListInterface.setOnMeetingsPreparedListener(mPreparedListener, mCalendar, 3);
        mHoursCallBack = new HoursCallBack();
        mHours.setOnHourClickListener(mHoursCallBack);
        mHours.setOnEventClickListener(mHoursCallBack);
        mHours.setOnEventLongClickListener(mHoursCallBack);

    }

    private final class HoursCallBack implements OnHourClickListener,
                              EventCardView.OnEventClickListener,
                              EventCardView.OnEventLongClickListener, View.OnClickListener {

        private Intent mIntent;
        private PopupWindow mWindow;
        private View mWindowContentView;

        @Override
        public void onEventClick(View view, EventCard eventCard, final int position) {
            // 短按进入该会议的详情页面
            // 如果是自己预定的会议，则可以进行对该会议的修改和删除
            toDetailsActivity(eventCard);
        }

        @Override
        public void onHourClick(int hour, boolean isHalf) {
            NewMeetingInfo newMeetingInfo = new NewMeetingInfo();
            if (mDept != null) {
                newMeetingInfo.setDept(new String[]{mDept.getDeptid(), mDept.getDeptname()});
            }
            if (mRoom != null) {
                newMeetingInfo.setRoom(new String[]{mRoom.getRoomid(), mRoom.getRoom()});
            }
            Calendar calendar = Calendar.getInstance();
            calendar.setTimeInMillis(mCalendar.getTimeInMillis());
            calendar.set(Calendar.HOUR_OF_DAY, hour);
            if (!isHalf) {
                // 如果点击的是下半部分，开始时间增加半个小时
                calendar.setTimeInMillis(calendar.getTimeInMillis() + 1000 * 60 * 30);
            }
            newMeetingInfo.setStartTime(calendar.getTimeInMillis());
            // 默认的结束时间是开始时间加上半个小时，也就是会议时长半个小时
            newMeetingInfo.setEndTime(calendar.getTimeInMillis() + 1000 * 60 * 30);

            Intent intent = getTargetIntentByClass(OrderOneMeetingActivity.class);
            Bundle bundle = new Bundle();
            bundle.putSerializable(PagerAllMeetingsFragment.NEW_MEETING_INFO_KEY, newMeetingInfo);
            intent.putExtras(bundle);
            startActivityForResult(intent, 1000);
        }

        @Override
        public boolean onEventLongClick(View cardView, EventCard eventCard, final int position) {
            cardView.animate().alpha(0).setDuration(200).start();
            expandMeetings(eventCard, cardView);
            return false;
        }

        /**
         * 展开会议
         * 长按会议，显示一个PopupWindow用来显示全部的会议信息
         * 以免因为高度不够而导致信息显示不全
         *
         * @param eventCard
         * @param cardView
         */
        private void expandMeetings(EventCard eventCard, final View cardView) {
            TextView title, time, room;
            mWindowContentView = getActivity().getLayoutInflater().inflate(R.layout.view_event_card, null);
            title = (TextView) mWindowContentView.findViewById(R.id.event_card_title);
            time = (TextView) mWindowContentView.findViewById(R.id.event_card_time);
            room = (TextView) mWindowContentView.findViewById(R.id.event_card_room);
            if (mWindow == null) {
                mWindow = new PopupWindow(mWindowContentView, ViewGroup.LayoutParams.WRAP_CONTENT,
                                                 ViewGroup.LayoutParams.WRAP_CONTENT, true);
                mWindow.setBackgroundDrawable(new BitmapDrawable());
            } else {
                mWindow.setContentView(mWindowContentView);
            }
            if (title != null) {
                title.setText(eventCard.getTitle());
            }
            if (time != null) {
                time.setText(eventCard.getSecondTitle());
            }
            if (room != null) {
                room.setText(eventCard.getDescription());
            }
            mWindow.showAsDropDown(cardView, (int) mScreen.dip2px(64), (int) -mScreen.dip2px(eventCard.getHeight()));
            mWindow.setOnDismissListener(new PopupWindow.OnDismissListener() {
                @Override
                public void onDismiss() {
                    cardView.animate().alpha(1).setDuration(200).start();
                }
            });
            View view = mWindow.getContentView();
            view.setTag(eventCard);
            view.setOnClickListener(this);
        }

        /**
         * 跳转到会议的详情页面
         *
         * @param card
         */
        private void toDetailsActivity(EventCard card) {
            Intent intent = getTargetIntentByClass(MeetingDetailsActivity.class);
            Bundle bundle = new Bundle();
            bundle.putSerializable(MeetingDetailsActivity.DETAILS_KEY, (MeetingByMonth) card.getTag());
            intent.putExtras(bundle);
            startActivityForResult(intent, 1000);
        }

        /**
         * 根据Class获取Intent
         *
         * @param cls
         * @return
         */
        private Intent getTargetIntentByClass(Class cls) {
            if (mIntent == null) {
                mIntent = new Intent();
            }
            mIntent.setClass(getActivity(), cls);
            return mIntent;
        }

        @Override
        public void onClick(View v) {
            toDetailsActivity((EventCard) v.getTag());
        }
    }

    /**
     * 加载会议信息的回调函数
     */
    private final class PreparedListener implements MeetingsListInterface.OnMeetingsPreparedListener {

        private ArrayList<MeetingByMonth> mMeetings;
        private ArrayList<MeetingByMonth> mStorage;
        private ArrayList<MeetingByMonth> mInfo;

        @Override
        public void onGetMeetings(List<MeetingByMonth> meetingBeans) {
            MeetingsController.Sort.orderByStartTimeDesc2(meetingBeans);
            mMeetings = (ArrayList<MeetingByMonth>) meetingBeans;
            mStorage = (ArrayList<MeetingByMonth>) mMeetings.clone();
            mInfo = (ArrayList<MeetingByMonth>) mMeetings.clone();
            Date date = new Date();
            filterMeetingByDate(date.getMonth() + 1, date.getDate());
            resetCards(mInfo);
            if (mRefresh != null) {
                mRefresh.onFinish(CalendarViews.REFRESH_SUCCESS);
            }
        }

        public ArrayList<MeetingByMonth> getMeetings() {
            return mMeetings;
        }

        public ArrayList<MeetingByMonth> getStorage() {
            return mStorage;
        }

        public ArrayList<MeetingByMonth> getInfo() {
            return mInfo;
        }
    }

    /**
     * 是否是同一天
     *
     * @param now
     * @param month
     * @param dayOfMonth
     * @return
     */
    private boolean isTheSameDay(Date now, int month, int dayOfMonth) {
        return now.getMonth() + 1 == month && now.getDate() == dayOfMonth;
    }

    /**
     * 根据日期过滤会议信息
     *
     * @param month
     * @param dayOfMonth
     */
    private ArrayList<MeetingByMonth> filterMeetingByDate(int month, int dayOfMonth) {
        ArrayList<MeetingByMonth> storage = mPreparedListener.getStorage();
        ArrayList<MeetingByMonth> info = new ArrayList<>();
        for (MeetingByMonth meeting : storage) {
            long millis = MeetingsController.getStartDateTimeInMillis(meeting.getTime());
            if (isTheSameDay(new Date(millis), month, dayOfMonth)) {
                info.add(meeting);
            }
        }
        return info;
    }

    /**
     * 根据日期过滤会议，用于选择会议室时
     *
     * @param month
     * @param dayOfMonth
     * @param base
     * @return
     */
    private ArrayList<MeetingByMonth> filterMeetingByDate(int month, int dayOfMonth, ArrayList<MeetingByMonth> base) {
        ArrayList<MeetingByMonth> storage = (ArrayList<MeetingByMonth>) base.clone();
        base.clear();
        for (MeetingByMonth meeting : storage) {
            long millis = MeetingsController.getStartDateTimeInMillis(meeting.getTime());
            if (isTheSameDay(new Date(millis), month, dayOfMonth)) {
                base.add(meeting);
            }
        }
        return base;
    }

    /**
     * 根据会议室过滤会议信息
     *
     * @param meetingRooms
     * @return
     */
    private ArrayList<MeetingByMonth> filterMeetingByRoom(MeetingRoom[] meetingRooms) {
        ArrayList<MeetingByMonth> info = new ArrayList<>();
        ArrayList<MeetingByMonth> storage = mPreparedListener.getStorage();
        for (MeetingByMonth byMonth : storage) {
            for (MeetingRoom room : meetingRooms) {
                if (room.getRoomid().equals(byMonth.getRoomid())) {
                    info.add(byMonth);
                    break;
                }
            }
        }
        int month = mCalendar.get(Calendar.MONTH) + 1;
        int day = mCalendar.get(Calendar.DAY_OF_MONTH);
        return filterMeetingByDate(month, day, info);
    }

    /**
     * 重置卡片
     *
     * @param meetingByMonths
     */
    private void resetCards(ArrayList<MeetingByMonth> meetingByMonths) {
        List<EventCard> eventCards = new ArrayList<>();
        for (MeetingByMonth meetingByMonth : meetingByMonths) {
            EventCard card = new EventCard();
            card.setTitle("主题：" + meetingByMonth.getTopic());
            String time = meetingByMonth.getTime();
            String temp = MeetingsController.getStartDateTime(time) + " ~ " + MeetingsController.getEndDateTime(time);
            card.setSecondTitle("时间：" + temp);
            card.setDescription("房间：" + meetingByMonth.getRoom());
            long mills = MeetingsController.getStartDateTimeInMillis(time);
            card.setHeight(getCardHeightByTime(time));
            card.setOffsetTop(getOffsetTopByHour(mills));
            card.setTag(meetingByMonth);
            eventCards.add(card);
        }
        mHours.setEventCards(eventCards);
    }

    /**
     * 根据时间获取事件卡片距离顶部的高度
     *
     * @param startTimeMillis
     * @return
     */
    private int getOffsetTopByHour(long startTimeMillis) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTimeInMillis(startTimeMillis);
        int hours = calendar.get(Calendar.HOUR_OF_DAY) * 2;
        int minutes = calendar.get(Calendar.MINUTE);
        return (int) (getScreen().dip2px(hours * HALF_AN_HOUR_HEIGHT /* 小时 */ +
                                                 (minutes / 60f) * (HALF_AN_HOUR_HEIGHT * 2)/* 分钟 */));
    }

    /**
     * 根据时长获取事件卡片的高度
     *
     * @param time
     * @return
     */
    private int getCardHeightByTime(String time) {
        long startMillis = MeetingsController.getStartDateTimeInMillis(time);
        long endMillis = MeetingsController.getEndDateTimeInMillis(time);
        long temp = endMillis - startMillis;
        Calendar calendar = Calendar.getInstance();
        calendar.setTimeInMillis(temp);
        int minutes = calendar.get(Calendar.MINUTE);
        return (int) getScreen().dip2px((minutes / 60f) * (HALF_AN_HOUR_HEIGHT * 2));
    }

    /**
     * 获取屏幕的信息
     *
     * @return
     */
    private ScreenUtil getScreen() {
        if (mScreen == null) {
            mScreen = new ScreenUtil(getActivity());
        }
        return mScreen;
    }

    @Override
    public String getHeaderText() {
        String text = "今天";
        if (!isToday()) {
            int offsetDays = getDayOfYear() - mToday;
            if (offsetDays == 1) {
                text = "明天";
            } else if (offsetDays == 2) {
                text = "后天";
            } else if (offsetDays == -1) {
                text = "昨天";
            } else if (offsetDays == -2) {
                text = "前天";
            } else {
                text = mCalendar.get(Calendar.DAY_OF_MONTH) + "日";
            }
        }
        return text;
    }

    /**
     * 是否是今天
     *
     * @return
     */
    private boolean isToday() {
        return mToday == getDayOfYear();
    }

    @Override
    public void prev() {
        changeDay(-1);
    }

    @Override
    public void next() {
        changeDay(1);
    }

    @Override
    public Calendar getDate() {
        return mCalendar;
    }

    @Override
    public void onSelectRoom(Dept dept, MeetingRoom[] meetingRooms) {
        mDept = dept;
        mRoom = meetingRooms[0];
        // 根据选择的会议室，过滤信息后，重置卡片显示
        ArrayList<MeetingByMonth> meetings = filterMeetingByRoom(meetingRooms);
        resetCards(meetings);
    }

    @Override
    public void onResult(int requestCode, int resultCode, Intent data) {
        mListInterface.setOnMeetingsPreparedListener(mPreparedListener, mCalendar, 3);
    }

    @Override
    public void onRefresh(OnRefreshListener onRefreshListener) {
        mRefresh = onRefreshListener;
        mListInterface.setOnMeetingsPreparedListener(mPreparedListener, mCalendar, 3);
    }

    /**
     * 改变日期
     *
     * @param day
     */
    private void changeDay(int day) {
        mCalendar.set(Calendar.DAY_OF_YEAR, getDayOfYear() + day);
        if (mMonth != mCalendar.get(Calendar.MONTH)) {
            mMonth = mCalendar.get(Calendar.MONTH);
            mListInterface.setOnMeetingsPreparedListener(mPreparedListener, mCalendar, 3);
        } else {
            log("DAY_VIEW", mCalendar.get(Calendar.MONTH) + "-" + mCalendar.get(Calendar.DAY_OF_MONTH));
            resetCards(filterMeetingByDate(mCalendar.get(Calendar.MONTH) + 1, mCalendar.get(Calendar.DAY_OF_MONTH)));
        }
    }

    /**
     * 获取某一天是一年中的哪一天
     *
     * @return
     */
    private int getDayOfYear() {
        return mCalendar.get(Calendar.DAY_OF_YEAR);
    }

}
